<?php
/**
 * Created by PhpStorm.
 * User: dell
 * Date: 2017/7/20
 * Time: 10:33
 */
namespace app\pay\controller;
use think\Controller;
use think\Request;
use think\Db;
use think\Validate;
class PayController extends Controller{


    public function  index(){
       //根据支付类型，1代表是支付宝，2代表是微信
        $payment_type = Request::instance()->param('payment_type');
        if($payment_type == 1){
            $alipay_config = config('alipay_config');
            /**************************请求参数**************************/
            //接收数据验证（拆分订单表和订单祥情表数据）
            //订单数据
            $order_data = [
                'user_id'=>1,//用户id
                'payment_method'=>'',//支付方式
                'payment_money'=>'0.01',//支付金额
                'status'=>0,//订单状态
                'created_time'=>time(),//创建订单时间
                'updated_time'=>time(),//修改订单时间
            ];
            $rule = [
                'payment_money'  => 'require',
            ];
            $msg = [
                'payment_money.require' => '金额不能为空',
            ];
            $validate = new Validate($rule,$msg);
            $result   = $validate->check($order_data);
            if(!$result){
                $error = $validate->getError();
                return json(['code'=>1,'msg'=>'FLASE','result'=>['error'=>$error]]);
            }
            //如果用户ID为空，则是未登录用户购买，根据手机号判断用户是否存在，存在的话提醒去登录，不存在，支付完成后用这个手机号注册用户（个人用户）
            if(empty($order_data['user_id'])){
               if(empty($order_data['phone'])){
                  return json(['code'=>1,'msg'=>'手机号不能为空']);
               }else{
                   $order_data['phone'] = '';
                   $order_data['email'] = '';
                   $order_data['order_user_type'] = 1;
               }
            }
            //订单详情数据
            $order_detail_data = [
                'goods_id'=>1,//产品ID
                'goods_num'=>'',//产品数量
                'goods_price'=>'',//产品价格
                'created_time'=>time(),
                'updated_time'=>time(),
            ];
            $rule = [
                'goods_id'  => 'require',
            ];
            $msg = [
                'goods_id.require' => '请选择购买的产品',
            ];
            $validate = new Validate($rule,$msg);
            $result   = $validate->check($order_detail_data);
            if(!$result){
                $error = $validate->getError();
                return json(['code'=>1,'msg'=>'FLASE','result'=>['error'=>$error]]);
            }
            //开始创建订单和订单详情
            Db::startTrans();
            //生成订单编号
            $out_trade_no = date('YmdHis') . rand(1000, 9999);
            $order_data['order_num'] = $out_trade_no;
            $order_re = Db::table('orders')->insert($order_data);
            if(!$order_re){
                Db::rollback();
                return json(['code'=>1,'msg'=>'生成订单失败','result'=>[]]);
            }
            $order_detail_data['order_num'] = $out_trade_no;
            $order_detail_re = Db::table('orders_details')->insert($order_detail_data);
            if(!$order_detail_re){
                Db::rollback();
                return json(['code'=>1,'msg'=>'生成订单失败','result'=>[]]);
            }
            Db::commit();
            $subject = 'test商品123';
            $total_fee = $order_data['payment_money'];
            //商品描述，可空
            $body = '';
            //构造要请求的参数数组，无需改动
            $parameter = array(
                "service" => $alipay_config['service'],
                "partner" => $alipay_config['partner'],
                "seller_id" => $alipay_config['seller_id'],
                "payment_type" => $alipay_config['payment_type'],
                "notify_url" => $alipay_config['notify_url'],
                "return_url" => $alipay_config['return_url'],

                "anti_phishing_key" => $alipay_config['anti_phishing_key'],
                "exter_invoke_ip" => $alipay_config['exter_invoke_ip'],
                "out_trade_no" => $out_trade_no,
                "subject" => $subject,
                "total_fee" => $total_fee,
                "body" => $body,
                "_input_charset" => trim(strtolower($alipay_config['input_charset']))
                //其他业务参数根据在线开发文档，添加参数.文档地址:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.kiX33I&treeId=62&articleId=103740&docType=1
                //如"参数名"=>"参数值"

            );
            //建立请求
            $alipaySubmit = new \Alipay\lib\AlipaySubmit($alipay_config);
            $html_text = $alipaySubmit->buildRequestForm($parameter, "get", "确认");
            echo $html_text;
        }elseif($payment_type == 2){
            //接收参数，验证
            $data = [
                'body'=>'订单描述',
                'attach'=>'订单标题',
                'out_trade_no'=>date('YmdHis').rand(10000,999999),
                'total_fee'=>'0.01',
                'product_id'=>rand(100000,999999),
            ];
            $validate = new Validate([
                ['body','require','请输入订单描述'],
                ['attach','require','请输入订单标题'],
                ['out_trade_no','require|alphaNum','订单编号输入错误|订单编号输入错误'],
                ['total_fee','require|number|gt:0','金额输入错误|金额输入错误|金额输入错误'],

            ]);
            if (!$validate->check($data)) {
                return json(['code'=>0,'msg'=>$validate->getError()]);
            }

            $host='http://'.$_SERVER['HTTP_HOST']; //获取当前域名
            $notify = new \Wxpay\lib\NativePay(); //实例化微信类
            $WxPayConfig = new \Wxpay\lib\WxPayConfig(); //实例化微信类
            $input = new \Wxpay\lib\WxPayUnifiedOrder(); //实例化微信类
            $input->SetBody($data['body']); //订单描述
            $input->SetOut_trade_no($data['out_trade_no']);//账单号
            $input->SetTotal_fee($data['total_fee']*100); //付款金额微信是以分为单位的，所以传过来的参数乘以100
            $input->SetNotify_url($host."/pay/Wxpay/notify");//回调地址
            $input->SetTrade_type("NATIVE");
            $input->SetProduct_id($data['product_id']);//商品id
            $result = $notify->GetPayUrl($input); //扫码模式二
            $codeurl = $result["code_url"];
            //这里可以加入你的订单入库代码(订单表和订单祥情表)


            return json(['code'=>0,'msg'=>'OK','result'=>['codeurl'=>$codeurl]]);
        }else{
            return;
        }

    }

    //已生成订单，然后去支付
    public function pay_orders(){

    }
    //支付宝同步返回，用于提示页面
    public function  alipay_return()
    {

        //同步验证，接受到的请求进行验证
        $alipay_config = config('alipay_config');
        $this->_notifyObj = new \Alipay\lib\AlipayNotify($alipay_config);
        $verifyResult = $this->_notifyObj->verifyReturn();
        if ($verifyResult)
        {
            $arr = Request::instance()->param();
            /*
             * array(18) {
                      ["/pay/alipay/backtome"] => string(0) ""
                      ["buyer_email"] => string(17) "1187058988@qq.com"
                      ["buyer_id"] => string(16) "2088902359168081"
                      ["exterface"] => string(25) "create_direct_pay_by_user"
                      ["is_success"] => string(1) "T"
                      ["notify_id"] => string(72)  "RqPnCoPT3K9%2Fvwbh3Ih20lxLHYGJ2kabhYI6wkmP3PgPIs92w%2BD7y12tabE4O3Imwppp"
                      ["notify_time"] => string(19) "2017-07-19 11:13:42"
                      ["notify_type"] => string(17) "trade_status_sync"
                      ["out_trade_no"] => string(18) "201707191112074503"
                      ["payment_type"] => string(1) "1"
                      ["seller_email"] => string(15) "pimc_cn@163.com"
                      ["seller_id"] => string(16) "2088621522746340"
                      ["subject"] => string(13) "test商品123"
                      ["total_fee"] => string(4) "0.01"
                      ["trade_no"] => string(28) "2017071921001004080256229419"
                      ["trade_status"] => string(13) "TRADE_SUCCESS"
                      ["sign"] => string(32) "ac039e28c907446014222faff45a1b50"
                      ["sign_type"] => string(3) "MD5"
                    }
             * */
            //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表
            $out_trade_no   = $arr['out_trade_no'];      //商户订单号
            $trade_no       = $arr['trade_no'];          //支付宝交易号
            $trade_status   = $arr['trade_status'];      //交易状态
            $total_fee      = $arr['total_fee'];         //交易金额
            $notify_id      = $arr['notify_id'];         //通知校验ID。
            $notify_time    = $arr['notify_time'];       //通知的发送时间。
            $buyer_email    = $arr['buyer_email'];       //买家支付宝帐号；

            $parameter = array(
                "out_trade_no"     => $out_trade_no,      //商户订单编号；
                "trade_no"     => $trade_no,          //支付宝交易号；
                "total_fee"      => $total_fee,         //交易金额；
                "trade_status"     => $trade_status,      //交易状态
                "notify_id"      => $notify_id,         //通知校验ID。
                "notify_time"    => $notify_time,       //通知的发送时间。
                "buyer_email"    => $buyer_email,       //买家支付宝帐号
            );

            if($arr['trade_status'] == 'TRADE_FINISHED' || $arr['trade_status'] == 'TRADE_SUCCESS') {
                if(!$this->checkorderstatus($out_trade_no)){
                    $this->orderhandle($parameter);  //进行订单处理，并传送从支付宝返回的参数；
                }
                return json(['code'=>0,'msg'=>'OK','result'=>[]]);
            }else {
//                echo "trade_status=".$_GET['trade_status'];
                return  json(['code'=>1,'msg'=>$arr['trade_status']]);
            }
        } else
        {
            return json(['code' => 1, 'msg' => '支付异常']);
        }

    }
    //支付宝异步提醒，用于更新订单状态
    public function  alipay_notify()
    {
        //接受到的请求进行验证
        $alipay_config = config('alipay_config');
        $this->_notifyObj = new \Alipay\lib\AlipayNotify($alipay_config);
        $verifyResult = $this->_notifyObj->verifyNotify();
        if ($verifyResult)
        {
            //验证成功
            $arr = Request::instance()->param();
            //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表
            $out_trade_no = $arr['out_trade_no'];      //商户订单号
            $trade_no = $arr['trade_no'];          //支付宝交易号
            $trade_status = $arr['trade_status'];      //交易状态
            $total_fee = $arr['total_fee'];         //交易金额
            $notify_id = $arr['notify_id'];         //通知校验ID。
            $notify_time = $arr['notify_time'];       //通知的发送时间。格式为yyyy-MM-dd HH:mm:ss。
            $buyer_email = $arr['buyer_email'];       //买家支付宝帐号；
            $parameter = array(
                "out_trade_no" => $out_trade_no, //商户订单编号；
                "trade_no" => $trade_no,     //支付宝交易号；
                "total_fee" => $total_fee,    //交易金额；
                "trade_status" => $trade_status, //交易状态
                "notify_id" => $notify_id,    //通知校验ID。
                "notify_time" => $notify_time,  //通知的发送时间。
                "buyer_email" => $buyer_email,  //买家支付宝帐号；
            );
            if ($arr['trade_status'] == 'TRADE_FINISHED' || $arr['trade_status'] == 'TRADE_SUCCESS')
            {
                if (!$this->checkorderstatus($out_trade_no))
                {
                    $this->orderhandle($parameter);  //进行订单处理，并传送从支付宝返回的参数；
                }

                echo "success";        //请不要修改或删除
            }
        }else
            {

                //验证失败
                echo "fail";
            }
        }
    //微信异步提醒
    public function wxpay_notify(){

        $xml = $GLOBALS['HTTP_RAW_POST_DATA']; //返回的xml
        file_put_contents(dirname(__FILE__).'/xml.txt',$xml); //记录日志 支付成功后查看xml.txt文件是否有内容 如果有xml格式文件说明回调成功
//file_get_contents(dirname(__FILE__).'/xml.txt');
        $xmlObj=simplexml_load_string($xml,'SimplexmlElement',LIBxml_NOCDATA);
        $xmlArr=json_decode(json_encode($xmlObj),true);
        $out_trade_no=$xmlArr['out_trade_no']; //订单号
        $total_fee=$xmlArr['total_fee']/100; //回调回来的xml文件中金额是以分为单位的
        $result_code=$xmlArr['result_code']; //状态
        if($result_code=='SUCCESS'){ //数据库操作
        //处理数据库操作 例如修改订单状态 给账户充值等等

            echo 'SUCCESS'; //返回成功给微信端 一定要带上不然微信会一直回调8次
            exit;
        }else{ //失败
            return;
            exit;
        }
    }
    //微信查询订单状态
    public function get_order_status(){
        $order_num = Request::instance()->param('order_num');
        $ordstatus = Db::table('orders')->where('order_num',$order_num)->value('status');
        if ($ordstatus == 1)
        {
            return json(['code'=>0,'msg'=>'OK','result'=>[]]);
        } else
        {
            return json(['code'=>1,'msg'=>'FALSE','result'=>[]]);
        }
    }
        //在线交易订单支付处理函数
        //函数功能：根据支付接口传回的数据判断该订单是否已经支付成功；
        //返回值：如果订单已经成功支付，返回true，否则返回false；
    function checkorderstatus($orderid)
    {

        $ordstatus = Db::table('orders')->where('order_num',$orderid)->value('status');
        if ($ordstatus == 1)
        {
            return true;
        } else
        {
            return false;
        }
    }

    //处理订单函数
    //更新订单状态，写入订单支付后返回的数据（支付宝）
    function orderhandle($parameter)
    {
        $orders_num = $parameter['out_trade_no'];
        $data['payment_trade_no'] = $parameter['trade_no'];
        $data['payment_trade_status'] = $parameter['trade_status'];
        $data['payment_total_fee'] = $parameter['total_fee'];
        $data['payment_notify_id'] = $parameter['notify_id'];
        $data['payment_notify_time'] = $parameter['notify_time'];
        $data['payment_buyer_email'] = $parameter['buyer_email'];
        $data['status'] = 1;
        Db::table('order')->where('orders_num',$orders_num)->update($data);

    }
    //微信订单处理
    public function wxpayhandle(){

    }
        //获取一个随机且唯一的订单号；
    function getordcode()
    {
        $Ord = M('Orderlist');
        $numbers = range(10, 99);
        shuffle($numbers);
        $code = array_slice($numbers, 0, 4);
        $ordcode = $code[0] . $code[1] . $code[2] . $code[3];
        $oldcode = $Ord->where("ordcode='" . $ordcode . "'")->getField('ordcode');
        if ($oldcode)
        {
            getordcode();
        } else
        {
            return $ordcode;
        }
    }
}